/**
  * @file    servo_motor.c
  * @author  LiuDongPeng
  * @version V0.1
  * @date    2022-12-25
  * @brief   舵机模块源文件
  *
  * @attention
  * 使用此bmp280模块, 用户需提供一个周期为20ms, 0.5ms~2.5ms时长的有效电平可调的定时器PWM输出通道, 例如:
  * STM32F103系列, 72MHz主频, 定时器PSC设置为72 - 1, ARR设置为20000 - 1,
  * STM32F407系列, 168MHz主频, 定时器PSC设置为168 - 1, ARR设置为20000 - 1
  *
  * @changelog
  * 2023-1-5	修改变量, 函数等的命名风格为小写字母加下划线组合
  */

#include "servo_motor.h"


/**
 * @brief 创建舵机对象
 * @param[out]	servo
 * @param[in]	pwmStart
 * @param[in]	pwmStop
 * @param[in]	setTimCCR
 * @return
 */
int servo_motor_create(servo_motor_t* servo, pwm_start_t pwm_start, pwm_stop_t pwm_stop, set_tim_ccr_t set_tim_ccr)
{
	if (servo == NULL || pwm_start == NULL || pwm_stop == NULL || set_tim_ccr == NULL)
		return -1;

	servo->pwm_start = pwm_start;
	servo->pwm_stop = pwm_stop;
	servo->set_tim_ccr = set_tim_ccr;

	servo_motor_init(servo);

	return 0;
}

/**
 * @brief 舵机初始化
 * @param[in]	servo
 * @return
 */
int servo_motor_init(servo_motor_t* servo)
{
	if (servo == NULL)
		return -1;

	servo->angle = 0;

	return 0;
}

/**
 * @brief 启动舵机
 * @param[in]	servo
 * @return
 */
int servo_motor_start(servo_motor_t* servo)
{
	if (servo == NULL)
		return -1;

	servo->pwm_start();

	return 0;
}

/**
 * @brief 停止舵机
 * @param[in]	servo
 * @return
 */
int servo_motor_stop(servo_motor_t* servo)
{
	if (servo == NULL)
		return -1;

	servo->pwm_stop();

	return 0;
}

/**
 * @brief 设置舵机角度
 * @param[in]	servo
 * @param[in]	angle	0° ~ 180°
 * @return
 */
int servo_motor_set_angle(servo_motor_t* servo, float angle)
{
	if (servo == NULL)
		return -1;

	/**
	 * Angle:		0° ~ 180°
	 * PWM Duty:	0.5ms/20ms ~ 2.5ms/20ms
	 * CCR:			duty * ARR
	 */

	servo->set_tim_ccr((uint16_t)(500 + (angle / 180.0 * 2000)));

	servo->angle = angle;

	return 0;
}

/**
 * @brief 获取舵机角度
 * @param servo
 * @return
 */
float servo_motor_get_angle(servo_motor_t* servo)
{
	if (servo == NULL)
		return -1;

	return servo->angle;
}
